﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using AutomatedDecisionMaking.Class;
using AutomatedDecisionMaking.Class.Algorithms;

namespace AutomatedDecisionMaking.GUI.CarefulChoiceWindow
{
    public partial class FrmCarefulChoice : Form
    {
        #region Pola prywatne, konstruktor i podstawowe aspekty graficzneokna
        private readonly CarefulChoiceAlgorithm _mAlgorithm;    /// Algorytm podejmowania decyzji
        private readonly int _mDecisionNo;                      /// Ilość podjętych decyzji

        ///<summary>
        /// Konstuktor okna wyboru ostrożnego.
        /// </summary>
        /// <param name="decisionMatrix">Macierz decyzji</param>
        public FrmCarefulChoice(DecisionMatrix decisionMatrix)
        {
            InitializeComponent();
            _mAlgorithm = new CarefulChoiceAlgorithm(decisionMatrix);
            _mDecisionNo = decisionMatrix.DecisionList.Count;
            ShowPanel1();
        }

        /// <summary>
        /// Wyświetlenie Panelu nr. 1
        /// </summary>
        private void ShowPanel1()
        {
            Panel1.Visible = true;
            Panel2.Visible = false;
            Panel3.Visible = false;
            Panel4.Visible = false;
        }

        /// <summary>
        /// Wyświetlenie Panelu nr. 2
        /// </summary>
        private void ShowPanel2()
        {
            Panel1.Visible = false;
            Panel2.Visible = true;
            Panel3.Visible = false;
            Panel4.Visible = false;
        }

        /// <summary>
        /// Wyświetlenie Panelu nr. 3
        /// </summary>
        private void ShowPanel3()
        {
            Panel1.Visible = false;
            Panel2.Visible = false;
            Panel3.Visible = true;
            Panel4.Visible = false;
        }

        /// <summary>
        /// Wyświetlenie Panelu nr. 4
        /// </summary>
        private void ShowPanel4()
        {
            Panel1.Visible = false;
            Panel2.Visible = false;
            Panel3.Visible = false;
            Panel4.Visible = true;
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad ładowania okna.
        /// Metoda ta przygotowuje podstawowy wygląd okna.
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void FrmCarefulChoice_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < _mDecisionNo; ++i)
            {
                this.p1DataGridView_Weights.Rows.Add();
                this.p1DataGridView_Weights.Rows[i].HeaderCell.Value = "D" + (i + 1);

                this.p3DataGridView_CarefulChoiceTable.Rows.Add();
                this.p3DataGridView_CarefulChoiceTable.Rows[i].HeaderCell.Value = "D" + (i + 1);
            }
        }
        #endregion

        #region Obsługa przycisków nawigacji
        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku next na panelu 1
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p1ButtonNext_Click(object sender, EventArgs e)
        {
            var weights = new List<double>();
            for (int i = 0; i < _mDecisionNo; ++i)
                weights.Add(Convert.ToDouble(p1DataGridView_Weights.Rows[i].Cells[0].Value));
            _mAlgorithm.SetWeights(weights);
            _mAlgorithm.CalculateSolution();
            UpdatePanel2();
            ShowPanel2();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku prev na panelu 2
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p2ButtonPrev_Click(object sender, EventArgs e)
        {
            ShowPanel1();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku next na panelu 2
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p2ButtonNext_Click(object sender, EventArgs e)
        {
            UpdatePanel3();
            ShowPanel3();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku prev na panelu 3
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p3ButtonPrev_Click(object sender, EventArgs e)
        {
            ShowPanel2();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku next na panelu 3
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p3ButtonNext_Click(object sender, EventArgs e)
        {
            UpdatePanel4();
            ShowPanel4();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku prev na panelu 4
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p4ButtonPrev_Click(object sender, EventArgs e)
        {
            ShowPanel3();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku begin na panelu 4
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p4ButtonBegin_Click(object sender, EventArgs e)
        {
            ShowPanel1();
        }
        #endregion

        #region Obsługa Panelu nr. 1
        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad zakończenia edycji
        /// dowolnej komórki tabeli wag.
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p1DataGridView_Weights_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                double doubleValue;
                string cellValue = p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                if (!(double.TryParse(cellValue, out doubleValue)))
                {
                    MessageBox.Show("Wprowadzona wartość musi być liczbą z zakresu <0; 1>!",
                                    "INFORMACJA!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }
                else if (doubleValue < 0 || doubleValue > 1)
                {
                    MessageBox.Show("Wprowadzona wartość musi być liczbą z zakresu <0; 1>!",
                                    "INFORMACJA!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }
            }
            catch(NullReferenceException exception){}

        }
        #endregion

        #region Obsługa Panelu nr. 2
        /// <summary>
        /// Aktualziacja wyglądu panelu nr. 2
        /// </summary>
        private void UpdatePanel2()
        {
            p2ListBox_MaxVal.Items.Clear();
            p2ListBox_MinVal.Items.Clear();

            var optimistDecision = _mAlgorithm.GetOptimistDecisionStr();
            var pessimistDecision = _mAlgorithm.GetPessimistDecisionStr();

            foreach (string s in optimistDecision)
                p2ListBox_MaxVal.Items.Add(s);

            foreach (string s in pessimistDecision)
                p2ListBox_MinVal.Items.Add(s);
        }
        #endregion

        #region Obsługa Panelu nr. 3
        /// <summary>
        /// Aktualziacja wyglądu panelu nr. 3
        /// </summary>
        private void UpdatePanel3()
        {
            var weights = _mAlgorithm.GetWeights();
            var optimistDecision = _mAlgorithm.GetOptimistDecision();
            var pessimistDecision = _mAlgorithm.GetPessimistDecision();

            for (int i = 0; i < _mDecisionNo; ++i)
            {
                p3DataGridView_CarefulChoiceTable.Rows[i].Cells[0].Value = weights[i];
                p3DataGridView_CarefulChoiceTable.Rows[i].Cells[1].Value = optimistDecision[i];
                p3DataGridView_CarefulChoiceTable.Rows[i].Cells[2].Value = pessimistDecision[i];
            }
        }
        #endregion

        #region Obsługa Panelu nr. 4
        /// <summary>
        /// Aktualziacja wyglądu panelu nr. 4
        /// </summary>
        private void UpdatePanel4()
        {
            p4ListBox_WeightedValue.Items.Clear();

            var weightedVal = _mAlgorithm.GetWeightedValuesStr();
            var maxVal = _mAlgorithm.GetMaxValue();
            var decision = _mAlgorithm.GetDecision();

            foreach (string s in weightedVal)
                p4ListBox_WeightedValue.Items.Add(s);

            p4TextBox_MaxWeightedVal.Text = maxVal.ToString();

            p4Label_Decision.Text = decision;

        }
        #endregion


    }
}
